#pragma once
#include "log.hpp"
#include <sys/time.h>
#include <atomic>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <regex>
#include<utility>

namespace ns_util
{
    static const string Root = "./temp/";
    class PathUtil
    {
        // 构建源文件路径/可执行文件路径/编译输出文件路径
        static string Path(const string &file_name, const string &suffix)
        {
            return Root + file_name + suffix;
        }

    public:
        static string Src(const string &file_name)
        {
            return Path(file_name, ".cpp");
        }

        static string CompileErr(const string &file_name)
        {
            return Path(file_name, ".compile_err");
        }

        static string Exe(const string &file_name)
        {
            return Path(file_name, ".exe");
        }

        static string Stdout(const string &file_name)
        {
            return Path(file_name, ".stdout");
        }
    };

    class FileUiil
    {
    public:
        static string CreatUniqueFileName()
        {
            struct timeval tmp;
            int ret = gettimeofday(&tmp, nullptr);
            if (ret)
            {
                return string();
            }

            static atomic<int> id(0);
            string file_name = to_string(tmp.tv_usec * 1000 + id);
            ++id;

            return file_name;
        }

        static bool WriteFile(const string &path, const string *code)
        {
            ofstream ofs(path);
            if (!ofs.is_open())
            {
                return false;
            }
            ofs.write((*code).c_str(), (*code).size());
            ofs.close();
            return true;
        }

        static string ReadFile(const string &path)
        {
            ifstream ifs(path);
            if (!ifs.is_open())
            {
                return string();
            }
            string ret;
            char c;
            while (ifs.get(c))
            {
                ret += c;
            }
            ifs.close();
            return ret;
        }
    };

    class StringUtil
    {
    public:
        static vector<string> SplitString(string &str, string sep)
        {
            // 忽略连续的分隔符
            vector<string> token;
            boost::split(token, str, boost::is_any_of(sep.c_str()), boost::algorithm::token_compress_on);
            return token;
        }
    };

    //代码的安全性检查
    // 定义危险函数列表
    const std::vector<std::string> DANGEROUS_FUNCTIONS = {
        // 系统调用与进程控制
        "system", "exec", "fork", "vfork", "execl", "execlp", "execle", "execv", "execvp", "execvpe",
        "clone", "setuid", "setgid", "seteuid", "setegid", "getuid", "getgid", "geteuid", "getegid",
        // 文件操作
        "fopen", "fclose", "remove", "rename", "open", "close", "read", "write", "lseek", "stat",
        "std::ifstream", "std::ofstream", "std::fstream",
        // 网络操作
        "socket", "connect", "bind", "listen", "accept", "send", "recv", "sendto", "recvfrom",
        // 信号处理
        "signal", "sigaction", "sigprocmask",
        // 内存操作
        "mmap", "munmap", "mprotect",
        // 休眠操作
        "sleep", "usleep", "std::this_thread::sleep_for",
        // 环境变量操作
        "putenv", "setenv", "unsetenv"};

    // 定义代码长度限制
    const int MAX_CODE_LENGTH = 6000;

    class CodeCheck
    {

    public:
        // 基于字符串匹配和正则表达式的检查方法 (有一定的局限性)
       static std::pair<bool, std::string> check_code_security(const std::string &code)
        {
            // 检查代码长度
            if (code.length() > MAX_CODE_LENGTH)
            {
                return {false, "代码长度超过限制"};
            }

            // 检查危险函数
            for (const auto &func : DANGEROUS_FUNCTIONS)
            {
                std::regex pattern("\\b" + func + "\\b");
                if (std::regex_search(code, pattern))
                {
                    return {false, "代码中使用了禁止的函数: " + func};
                }
            }

            return {true, "代码安全"};
        }
    };
}